package bancosys.tec.services;

import java.net.URL;
import java.util.List;

import jmine.tec.services.api.ServicesPage;

import org.springframework.transaction.TransactionStatus;

import bancosys.tec.datadigester.DigesterBean;
import bancosys.tec.services.input.driver.bean.ServicePageHeader;
import bancosys.tec.services.input.driver.processor.ThreadSafeServiceProcessor;

/**
 * Test case abstrato para testes que consistem em executar arquivos.
 * 
 * @author lundberg
 */
public abstract class DataDigesterIntegrationTestCase extends IntegrationTestCase {

    /**
     * 
     */
    public DataDigesterIntegrationTestCase() {
        super();
    }

    /**
     * @param name
     */
    public DataDigesterIntegrationTestCase(String name) {
        super(name);
    }

    /**
     * @param url
     */
    public DataDigesterIntegrationTestCase(URL url) {
        super(url);
    }

    /**
     * Efetua o teste de execução de arquivo.
     */
    @Override
    protected void doRunTest() throws Throwable {
        String fileCode = this.getFileCode(this.getTestInput());
        this.validateTest(fileCode, this.getTestInput());
        URL testInput = this.getTestInput();
        TransactionStatus status = this.getHelper().getTransactionStatus();
        boolean rollback = true;
        try {
            this.getDataDigesterController().process(fileCode, testInput.getFile(), testInput.openStream());
            rollback = false;
        } finally {
            if (rollback) {
                this.getHelper().rollback(status);
            } else {
                this.getHelper().commit(status);
            }
        }
    }

    /**
     * Valida o arquivo de teste
     * 
     * @param testInput testInput
     * @throws Throwable Throwable
     */
    protected void validateTest(String fileCode, URL testInput) throws Throwable {
        if (!this.shouldValidate(testInput)) {
            return;
        }
        this.validateDigesterBean(this.digestFile(fileCode, testInput));
    }

    /**
     * Valida um DigesterBean
     * 
     * @param bean bean
     * @throws Throwable Throwable
     */
    protected void validateDigesterBean(DigesterBean bean) throws Throwable {
        if (bean instanceof ServicePageHeader) {
            this.validateServicePageHeader((ServicePageHeader) bean);
        }
    }

    /**
     * Valida um ServicePageHeader
     * 
     * @param bean bean
     * @throws Throwable Throwable
     */
    protected void validateServicePageHeader(ServicePageHeader bean) throws Throwable {
        ThreadSafeServiceProcessor processor = new ThreadSafeServiceProcessor(this.getServicesController());
        List<ServicesPage> pages = processor.getServicesPages(bean);
        this.getServicesController().getServicesPageValidator().validate(pages);
    }

    /**
     * Verifica se o arquivo deve ser validado antes da execução propriamente dita
     * 
     * @param testInput testInput
     * @return boolean
     */
    protected boolean shouldValidate(URL testInput) {
        return true;
    }
}
